<template>
     <view class="qh-scroll-view flex-column" :style="boxStyle" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
          <!-- #ifdef MP-ALIPAY -->
          <view class="qh-scroll-view__loading flex-end-cn" :style="refresherStyle">
               <view class="circle" :class="{'move1': moveY > 0}" :style="'margin-right:' + marginX + 'rpx'"></view>
               <view class="circle" :class="{'move2': moveY > 0}"></view>
               <view class="circle" :class="{'move3': moveY > 0}" :style="'margin-left:' + marginX + 'rpx'"></view>
          </view>
          <!-- #endif -->
          <scroll-view :scroll-y="scrollY" class="scroll-view" style="height: 100%;" :scroll-top="scroll_top" :show-scrollbar="false" @scrolltoupper="scrolltoupper" @scrolltolower="scrolltolower" :refresher-enabled="refresherEnabled" :lower-threshold="lowerThreshold" @refresherrefresh="refresherrefresh" :refresher-triggered="refresherTriggered" :refresher-background="refresherBackground" @scroll="scroll">
               <view class="scroll-view-content" :style="'background-color:' + contentBackground">
                    <slot></slot>
                    <view v-if="empty" class="qh-empty-data-box flex-cn-cn">
                         <qh-empty-data></qh-empty-data>
                    </view>
                    <qh-loading v-model="lowerTriggered" row size="small" text="加载中..." color="#999999"></qh-loading>
                    <qh-loaded-tip v-if="loaded"></qh-loaded-tip>
               </view>
          </scroll-view>
     </view>
</template>

<script>
// 仅支持上下滚动
export default {
     name: "qh-scroll-view",
     props: {
          scrollY: {
               type: Boolean,
               default: true,
          }, //是否允许滚动
          refresherEnabled: Boolean, //是否允许下拉刷新
          refresherTriggered: Boolean, //是否正在下拉刷新
          refresherBackground: {
               type: String,
               default: 'transparent'
          }, //下拉刷新的背景颜色
          contentBackground: {
               type: String,
               default: 'transparent'
          }, //scroll-view内部的颜色
          scrollTop: Number, //滚动距离顶部的距离（单位px）
          lowerEnabled: {
               type: Boolean,
               default: true,
          }, //是否允许上拉加载更多
          lowerTriggered: Boolean, //是否正在上拉加载更多
          lowerThreshold: [String, Number], //距底部多远时（单位px），触发 scrolltolower 事件
          parentElName: String, //父级元素的id或者类名（如：.name或#name）  注意：在父级中必须唯一，不传height时为必传
          height: Number, //scroll-view的高度（单位px）
          loaded: Boolean, //是否显示加载完毕提示
          empty: Boolean, //是否显示空提示
          barStatus: {
               type: Boolean,
               default: true,
          },
          barStatusHeight: Number
     },
     emits: ['scrolltolower', 'refresherrefresh', 'init', 'scroll'],
     data () {
          return {
               // #ifdef MP-ALIPAY
               moveY: 0,
               lastMoveY: 0,
               moving: false,
               // #endif
               parentHeight: 1500,
               top: 0, //滚动时的scrollTop
               scroll_top: 0, //scroll-view组件传参的scrollTop
               contentHeight: 0,
               lastScrollTop: 0,
          };
     },
     computed: {
          boxStyle () {
               if (this.barStatus) {
                    return `height:${(this.height ? this.height : this.parentHeight) - this.barStatusHeight}px`
               } else {
                    return `height:${this.height ? this.height : this.parentHeight}px`
               }
          },
          // #ifdef MP-ALIPAY
          refresherStyle () {
               return `height:${this.moveY >= 30 ? this.moveY : 0}px;background-color:${this.refresherBackground};`;
          },
          marginX () {
               let x = this.moveY <= 24 ? -24 : (this.moveY >= 96 ? 8 : ((-24 + this.moveY / 3)));
               // console.log('marginX', this.moveY, x);
               return x;
          },
          // #endif
     },
     mounted () {
          this.$nextTick(() => {
               // console.log('this.height', this.height);
               !this.height && this.parentElName && this.$nextTick(() => {
                    this.$emit('init', this.parentElName, (height) => {
                         // console.log('this.parentHeight', height)
                         this.parentHeight = height;
                    })
               })
          })
     },
     methods: {
          //开始下拉
          touchStart (e) {
               // #ifdef MP-ALIPAY
               if (!this.refresherEnabled || this.top > 5) return;
               this.moving = true;
               // #endif
          },
          //正在下拉
          touchMove (e) {
               // #ifdef MP-ALIPAY
               if (!this.moving) return;
               if (e.touches.length != 1) return;

               if (!this.lastMoveY) {
                    this.lastMoveY = e.touches[0].clientY;
               }
               let diff = e.touches[0].clientY - this.lastMoveY; // 和上次比,移动的距离 (小于0向下,大于0向上)
               let y = this.moveY + diff * 0.4; // 越往下,高度变化越小
               if (y < 0) return;
               if (y >= 96) {
                    y = 96;
               }
               this.lastMoveY = e.touches[0].clientY;
               this.moveY = y;
               // #endif
          },
          //下拉结束
          touchEnd () {
               // #ifdef MP-ALIPAY
               if (!this.moving) return;
               this.moving = false;
               this.lastMoveY = 0;
               if (this.moveY >= 64) {
                    this.refresherrefresh();
                    if (this.moveY != 96) {
                         this.moveY = 96;
                    }
               } else {
                    this.moveY = 0;
               }
               // #endif
          },
          // 滚动到顶部
          scrolltoupper (e) {
               this.$emit('scrolltoupper');
          },
          //滚动
          scroll (event) {
               this.top = event.detail.scrollTop;
               this.$emit('scroll', event);
               // // #ifdef MP-WEIXIN
               // if (this.$store.osName == 'android') {
               //      const scrollTop = event.detail.scrollTop;
               //      const lastScrollTop = this.lastScrollTop;

               //      if (scrollTop > lastScrollTop) {
               //           // 向下滚动
               //           const scrollViewHeight = this.height ? this.height : this.parentHeight;
               //           const query = uni.createSelectorQuery().in(this);
               //           query.select('.scroll-view').boundingClientRect((rect) => {
               //                // console.log('rect', rect)
               //                const scrollContentHeight = rect.height;
               //                if (scrollTop + scrollViewHeight >= scrollContentHeight - 10) {
               //                     this.$emit('scrolltolower');
               //                }
               //           }).exec();
               //      }
                    
               //      this.lastScrollTop = scrollTop;
               // }
               // // #endif
          },
          //触发上拉加载事件
          scrolltolower () {
               if (!this.lowerEnabled) return;
               this.$emit('scrolltolower');
               // // #ifdef MP-ALIPAY
               // this.$emit('scrolltolower');
               // // #endif
               // // #ifdef MP-WEIXIN
               // if (this.$store.osName == 'ios') {
               //      this.$emit('scrolltolower');
               // }
               // // #endif
          },
          //触发下拉刷新事件
          refresherrefresh () {
               this.$emit('refresherrefresh');
          },
     },
     watch: {
          refresherTriggered (n, o) {
               if (n != o && !n) {
                    this.moving = false;
                    this.moveY = 0;
               }
          },
          lowerTriggered (n, o) {
               if (n != o && !n && this.top + 20 > (this.height ? this.height : this.parentHeight)) {
                    this.$nextTick(() => {
                         this.top += 20;
                         this.scroll_top = this.top;
                    })
               }
          },
          scrollTop (n) {
               this.scroll_top = n;
               this.top = n;
          },
     },
}
</script>

<style lang="scss">
.qh-scroll-view {
     width: 100%;
     /* #ifdef MP-WEIXIN */
     height: 100%;
     /* #endif */
     /* #ifdef MP-ALIPAY */
     height: 300rpx;
     /* #endif */
     position: relative;

     /* #ifdef MP-ALIPAY */
     .qh-scroll-view__loading {
          width: 100%;
          height: 0px;
          transition: 0.1s;
          overflow: hidden;

          .circle {
               width: 16rpx;
               height: 16rpx;
               border-radius: 50%;
               background-color: rgba(0, 0, 0, 0.3);
               margin: 0 8rpx 24rpx;
               transition: 0.5s;

               &.move1 {
                    animation: move1 1.3s linear infinite;
               }

               &.move2 {
                    animation: move2 1.3s linear infinite;
               }

               &.move3 {
                    animation: move3 1.3s linear infinite;
               }
          }

          @keyframes move3 {
               100% {
                    background-color: rgba(0, 0, 0, 0.3);
               }

               90% {
                    background-color: rgba(0, 0, 0, 0.7);
               }

               60% {
                    background-color: rgba(0, 0, 0, 0.3);
               }
          }

          @keyframes move2 {
               100% {
                    background-color: rgba(0, 0, 0, 0.3);
               }

               60% {
                    background-color: rgba(0, 0, 0, 0.7);
               }

               30% {
                    background-color: rgba(0, 0, 0, 0.3);
               }
          }

          @keyframes move1 {
               100% {
                    background-color: rgba(0, 0, 0, 0.3);
               }

               30% {
                    background-color: rgba(0, 0, 0, 0.7);
               }

               0% {
                    background-color: rgba(0, 0, 0, 0.3);
               }
          }
     }

     /* #endif */
}
</style>
